package com.tq.auth.client;

import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * OAuth2 调试控制器
 * 模拟前端 OAuth2 授权回调，执行 code -> token -> userinfo 流程
 *
 * @author TqCoder
 * @since 2.0.0
 */
@RestController
@Slf4j
public class OAuth2DebugController {

    /* ==================== 认证中心端点 ==================== */
    private static final String TOKEN_URL      = "http://127.0.0.1:8011/oauth2/token";
    private static final String USER_INFO_URL  = "http://127.0.0.1:8011/userinfo";

    /* ==================== 客户端配置 ==================== */
    private static final String CLIENT_ID      = "demo-client";
    private static final String CLIENT_SECRET  = "admin";
    private static final String GRANT_TYPE     = "authorization_code";
    private static final String REDIRECT_URI   = "http://127.0.0.1:8080/debug/callback";

    /* ==================== 子系统配置 ==================== */
    private static final String FRONTEND_WELCOME_URL = "http://127.0.0.1:8080/welcome?info=";

    /* ==================== 其他参数 ==================== */
    private static final String HEADER_CONTENT_TYPE  = "Content-Type";
    private static final String CONTENT_TYPE_FORM    = "application/x-www-form-urlencoded";
    private static final String HEADER_AUTHORIZATION = "Authorization";
    private static final String BEARER_PREFIX        = "Bearer ";

    /**
     * OAuth2 授权回调处理
     */
    @GetMapping("/debug/callback")
    public void handleCallback(@RequestParam String code,
                               @RequestParam(required = false) String state,
                               HttpServletResponse servletResponse) throws IOException {

        log.info("收到授权码: {}", code);
        log.info("state: {}", state);

        // ===== 第一步：code -> token =====
        HttpResponse tokenResp = codeToToken(code);
        if (!tokenResp.isOk()) {
            throw new RuntimeException("获取 access token 失败，状态码: " + tokenResp.getStatus());
        }
        String accessToken = JSONUtil.parseObj(tokenResp.body()).getStr("access_token");

        // ===== 第二步：token -> userinfo =====
        String userInfoJson = tokenToUserInfo(accessToken);

        // ===== 第三步：重定向到前端 =====
        String targetUrl = FRONTEND_WELCOME_URL +
                           URLEncoder.encode(userInfoJson, StandardCharsets.UTF_8);
        log.info("[Redirect] 跳转到前端地址: {}", targetUrl);

        servletResponse.sendRedirect(targetUrl);
    }

    /**
     * 使用 access token 获取用户信息
     */
    private static String tokenToUserInfo(String accessToken) {
        HttpResponse infoResp = HttpDebugUtils.get(
                USER_INFO_URL,
                Map.of(HEADER_AUTHORIZATION, BEARER_PREFIX + accessToken)
        );

        if (!infoResp.isOk()) {
            throw new RuntimeException("获取 user info 失败，状态码: " + infoResp.getStatus());
        }
        return infoResp.body();
    }

    /**
     * 使用授权码换取 access token
     */
    private static HttpResponse codeToToken(String code) {
        Map<String, Object> form = new HashMap<>();
        form.put("grant_type", GRANT_TYPE);
        form.put("code", code);
        form.put("redirect_uri", REDIRECT_URI);
        form.put("client_id", CLIENT_ID);
        form.put("client_secret", CLIENT_SECRET);

        return HttpDebugUtils.postForm(
                TOKEN_URL,
                form,
                Map.of(HEADER_CONTENT_TYPE, CONTENT_TYPE_FORM)
        );
    }
}
